/**
 * @file RinexAmbData.hpp
 * Encapsulate satellite upd data, including I/O
 */

//============================================================================
//
//  Shoujian Zhang, Wuhan University, 2012
//
//============================================================================

#ifndef GPSTK_RinexAmbData_INCLUDE
#define GPSTK_RinexAmbData_INCLUDE

#include "DataStructures.hpp"
#include "SatID.hpp"
#include "RinexAmbBase.hpp"
#include "YDSTime.hpp"
#include "CommonTime.hpp"
#include "TypeID.hpp"
#include "SourceID.hpp"
#include "Variable.hpp"
#include <iomanip>

namespace gpstk
{
   /** @addtogroup ephemstore */
   //@{

      /**
       * This class encapsulates data for satellite udp with format similar
       * with the format of the RINEX Clock file, and is used in conjuction with 
       * class RinexAmbStream, which handles the I/O, and RinexAmbHeader, which 
       * holds information from the satellite upd file header.
       *
       * @code
       *
       *    RinexAmbStream ss("igs14080.clk_30s");
       *    RinexAmbHeader sh;
       *    RinexAmbData sd;
       *
       *    ss >> sh;
       *
       *    while (ss >> sd)
       *    {
       *       // Interesting stuff...
       *    }    
       *
       *    RinexAmbStream ssout("myfile.clk_30s", ios::out);
       *    ssout << sh;
       *    for(...) 
       *    {
       *          // perhaps modify sd
       *       ssout << sd
       *    }
       *
       * @endcode
       *
       * @sa gpstk::RinexAmbHeader and gpstk::RinexAmbStream for more information.
       */
   class RinexAmbData : public RinexAmbBase
   {
   public:

         /// Constructor.
      RinexAmbData() 
          :firstEpoch(true)
      { clear(); }
     
         /// Destructor
      virtual ~RinexAmbData() 
      {}

         /// Debug output function.
      virtual void dump(std::ostream& s=std::cout) const throw();

         ///@name data members
         //@{
      bool firstEpoch;

      CommonTime newTime;
      CommonTime oldTime;
      CommonTime currentTime;

      /// store the epoch-amb-est-data
      epochVarEstDataMap epochAmbEstData;
      VariableEstDataMap currentAmbEstData;

         //@}
      
   protected:


      void clear(void) throw()
      {
         epochAmbEstData.clear();
      }

         /** Writes the formatted record to the FFStream \a s.
          *  @warning 
          *     This function is currently unimplemented
          */
      virtual void reallyPutRecord(FFStream& s) const 
         noexcept(false);

         /**
          * This function reads a record from the given FFStream.
          * If an error is encountered in retrieving the record, the 
          * stream is reset to its original position and its fail-bit is set.
          *
          * @throws StringException 
          *    when a StringUtils function fails
          * @throws FFStreamError 
          *    when exceptions(failbit) is set and
          *    a read or formatting error occurs.  This also resets the
          *    stream to its pre-read position.
          */
      virtual void reallyGetRecord(FFStream& s) 
         noexcept(false);
   };

   //@}

}  // namespace

#endif // GPSTK_RinexAmbData_INCLUDE
